package com.sf.management.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.sf.appointment.domain.BusServiceItem;
import com.sf.appointment.mapper.BusServiceItemMapper;
import io.jsonwebtoken.lang.Assert;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sf.management.mapper.BusBpmnInfoMapper;
import com.sf.management.domain.BusBpmnInfo;
import com.sf.management.service.IBusBpmnInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * 流程定义明细Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-03-26
 */
@Service
@Transactional
public class BusBpmnInfoServiceImpl implements IBusBpmnInfoService 
{
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;

    @Autowired
    private RepositoryService repositoryService;


    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private BusServiceItemMapper  busServiceItemMapper;

    /**
     * 查询流程定义明细
     * 
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public BusBpmnInfo selectBusBpmnInfoById(Long id)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<BusBpmnInfo> selectBusBpmnInfoList(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoList(busBpmnInfo);
    }

    /**
     * 新增流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.insertBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 修改流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.updateBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     * 
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBusBpmnInfoByIds(Long[] ids)
    {




        return busBpmnInfoMapper.deleteBusBpmnInfoByIds(ids);
    }

    /**
     * 删除流程定义明细信息
     * 
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    public void deleteBusBpmnInfoById(Long id)
    {

        if(StringUtils.isEmpty(id+"")){
            throw new RuntimeException("非法操作");
        }

        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.selectBusBpmnInfoById(id);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(busBpmnInfo.getProcessDefinitionKey()).
                processDefinitionVersion(busBpmnInfo.getVersion().intValue()).singleResult();
        busBpmnInfoMapper.deleteBusBpmnInfoById(id);
        List<ProcessInstance> list1 = runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinition.getId()).processDefinitionVersion(busBpmnInfo.getVersion().intValue()).list();
        for (ProcessInstance processInstance : list1) {
            String businessKey = processInstance.getBusinessKey();
            if (!StringUtils.isEmpty(businessKey)) {
                Long businessKey1 = Long.parseLong(businessKey);
                BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(businessKey1);
                if (busServiceItem == null) {
                    throw new RuntimeException("操作出错");
                }
                Integer auditStatus = busServiceItem.getAuditStatus();
                if (BusServiceItem.AUDITSTATUS_AUDITING.equals(auditStatus)) {
                    busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_INIT);
                    busServiceItemMapper.updateBusServiceItem(busServiceItem);
                }
            }
        }
        repositoryService.deleteDeployment(processDefinition.getDeploymentId(), true);

    }

    @Override
    public void deploy(MultipartFile file, String bpmnLabel, Integer bpmnType, String info) throws IOException {
        if (file==null||file.isEmpty()){
            throw new RuntimeException("文件不正确");
        }
        if (bpmnLabel==null||bpmnLabel.isEmpty()){
            throw new RuntimeException("文件名称不正确");
        }
        if (bpmnType==null){
            throw new RuntimeException("类型不正确");
        }
        if (info==null||info.isEmpty()){
            throw new RuntimeException("备注不正确");
        }
        String originalFilename = file.getOriginalFilename();
// 获取文件扩展名
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        if (!fileExtension.equals("bpmn")) {
            throw new RuntimeException("文件格式不正确");
        }
        InputStream inputStream = file.getInputStream();

        Deployment deploy = repositoryService.createDeployment().addInputStream(bpmnLabel, inputStream).deploy();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();

        int version = processDefinition.getVersion();
        String key = processDefinition.getKey();
        Date deploymentTime = deploy.getDeploymentTime();
        Long version1=new Long(version);
        BusBpmnInfo busBpmnInfo = new BusBpmnInfo();
        busBpmnInfo.setBpmnLabel(bpmnLabel);
        busBpmnInfo.setProcessDefinitionKey(key);
        busBpmnInfo.setVersion(version1);
        busBpmnInfo.setBpmnType(bpmnType);
        busBpmnInfo.setInfo(info);
        busBpmnInfo.setDeployTime(deploymentTime);
        busBpmnInfoMapper.insertBusBpmnInfo(busBpmnInfo);

    }

    @Override
    public void bpmnInfo(String type, Long id, HttpServletResponse response) throws IOException {
        Assert.notNull(id,"id不能为空");
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.selectBusBpmnInfoById(id);
        if (busBpmnInfo==null){
            throw new RuntimeException("id不合法");
        }
        if ("xml".equals(type)){
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(busBpmnInfo.getProcessDefinitionKey()).processDefinitionVersion(busBpmnInfo.getVersion().intValue()).singleResult();
            InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
            IOUtils.copy(resourceAsStream,response.getOutputStream());
        }
        else if ("png".equals(type)){
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(busBpmnInfo.getProcessDefinitionKey()).processDefinitionVersion(busBpmnInfo.getVersion().intValue()).singleResult();
            InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
            DefaultProcessDiagramGenerator processDiagramGenerator=new DefaultProcessDiagramGenerator();
            BpmnModel bpmnModel=repositoryService.getBpmnModel(processDefinition.getId());
            InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel,
                    Collections.emptyList(),
                    Collections.emptyList(),
                    "宋体",
                    "宋体",
                    "宋体");
            IOUtils.copy(inputStream,response.getOutputStream());
        }
        else {
            throw new RuntimeException("操作错误");
        }


    }
}
